#pragma once

#include "Common.h"

// 单例模式
class CentralCache
{
public:
    static CentralCache* GetInstance()
    {
        return &_sInst;
    }

    // 获取一个非空的span
    Span* GetOneSpan(SpanList& list, size_t byte_size);

    // 从中心缓存中获取一定量的对象给thread cache
    size_t FetchRangeObj(void*& start, void*& end, size_t batchNum, size_t size);


private:
    SpanList _spanlists[NFREELIST];

private:
    CentralCache()
    {}

    CentralCache(const CentralCache&) = delete;
    CentralCache& operator=(const CentralCache&) = delete;

    static CentralCache _sInst;
};



CentralCache CentralCache::_sInst;

// 获取一个非空的span
Span* CentralCache::GetOneSpan(SpanList &list, size_t byte_size)
{
    // ....
    return nullptr;
}

// 从中心缓存中获取一定量的对象给thread cache
size_t CentralCache::FetchRangeObj(void *&start, void *&end, size_t batchNum, size_t size)
{
    size_t index = SizeClass::Index(size);
    _spanlists[index].mtx.lock();

    Span* span = GetOneSpan(_spanlists[index], size);
    assert(span);
    assert(span->_freeList);

    // 从span中获取batchNum个对象
    // 如果不够batchNum个，有多少拿多少
    start = span->_freeList;
    end = start;

    size_t i = 0;
    size_t actualNum = 1;

    while (i < batchNum - 1 && NextObj(end) != nullptr)
    {
        end = NextObj(end);
        ++i;
        ++actualNum;
    }

    span->_freeList = NextObj(end);
    NextObj(end) = nullptr;

    _spanlists[index].mtx.unlock();

    return actualNum;
}